package com.xiaode.controller.app.student.example;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.jfinal.aop.Before;
import com.jfinal.kit.Ret;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Page;
import com.jfinal.plugin.activerecord.Record;
import com.jfinal.plugin.activerecord.tx.Tx;
import com.jfinal.plugin.redis.Cache;
import com.jfinal.plugin.redis.Redis;
import com.xiaode.common.constant.Const;
import com.xiaode.common.model.*;
import com.xiaode.common.model.dto.example.ExampleTaskDTO;
import com.xiaode.common.model.dto.notice.NoticeDTO;
import com.xiaode.common.model.dto.notice.TaskInfoDTO;
import com.xiaode.exce.EnumError;
import com.xiaode.util.ChatUtil;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;


public class ExampleService {
    /**
     * 查询榜样信息
     *
     * @param studentId 学生id
     * @return
     * @throws Exception
     */
    public Ret findBindExample(Integer userId, Integer studentId, Integer state) throws Exception {
    	studentId = studentId == null ? userId : studentId;
        Example example;
        if (state != null) {
            example = Example.dao.findFirst("SELECT * FROM example WHERE studentId = ? AND state = ? AND isDele = 0", studentId, state);
        } else {
            example = Example.dao.findFirst("SELECT * FROM example WHERE studentId = ? AND isDele = 0", studentId);
        }
        return Ret.ok("example", example);
    }

    public Ret findExample(Integer exId) throws Exception {
//        Example example = Example.dao.findById(exId);
        Example example = Example.dao.findFirst("SELECT * FROM `example` WHERE id = ? AND isDele = 0", exId);
        return Ret.ok("example", example);
    }

    /**
     * 添加新的榜样
     *
     * @return
     */
    public Ret addExample(String pic, String name, String label, String brief, String keyWord, Integer stuId, String reason, Integer characterType) throws Exception {
        name = name.trim();
        //查询该学生是否已经创建过榜样,或者榜样正在审核过程中
        Example stuExample = Example.dao.findFirst("SELECT id FROM example where studentId = ? AND isDele = 0", stuId);
        if (BeanUtil.isNotEmpty(stuExample)) {
            return Ret.fail().set("error", EnumError.EXAMPLE_IS_FULL.getObj());
        }
        Example example = new Example();
        //榜样信息不存在 ,则直接添加
        example.setName(name);
        example.setLabel(label);
        example.setBrief(brief);
        example.setPictureUrl(pic);
        example.setReason(reason);
        example.setCharacterType(characterType);
        example.setKeyWord(keyWord);
        example.setStudentId(stuId);
        example.setFounderId(stuId);
        example.setFounderIdentity(1);
        example.setSumState(1);
        example.setState(1);
        example.setAddTime(LocalDateTime.now());
        example.setUpdateTime(LocalDateTime.now());
        example.save();

        //查询是否绑定教师 如果绑定教师则发送通知
        TeacherStudent ts = TeacherStudent.dao.findFirst("SELECT * FROM teacher_student WHERE state = 2 AND studentId = ?", stuId);
        if (BeanUtil.isNotEmpty(ts)) {
            //如果已经绑定了教师 则发送通知
            Cache redis = Redis.use();
            Student o = redis.get(Const.user.Student + stuId);
            NoticeDTO noticeDTO = new NoticeDTO();
            noticeDTO.setName(o.getName());
            noticeDTO.setAccountId(o.getAccountId());
            noticeDTO.setPic(o.getAvatarUrl());
            noticeDTO.setSex(o.getSex());
            noticeDTO.setType(10);
            noticeDTO.setId(stuId);
            TaskInfoDTO taskInfoDTO = new TaskInfoDTO();
            taskInfoDTO.setTaskType(3);
            ArrayList<Integer> list = new ArrayList<>();
            Example first = Example.dao.findFirst("SELECT id  FROM example WHERE studentId = ? AND isDele = 0 AND state = 1", stuId);
            list.add(first.getId());
            taskInfoDTO.setTaskIdList(list);
            ArrayList<TaskInfoDTO> taskInfoDTOS = new ArrayList<>();
            taskInfoDTOS.add(taskInfoDTO);
            noticeDTO.setTaskInfos(taskInfoDTOS);
            ArrayList<Integer> list1 = new ArrayList<>();
            Admin o1 = redis.get(Const.user.Admin + ts.getTeacherId());
            list1.add(o1.getAccountId());
            ChatUtil.sendNotice(JSONUtil.toJsonStr(noticeDTO), 1, list1);
        }
        return Ret.ok();
    }

    /**
     * 添加/修改任务
     *
     * @param stuId 学生id
     * @return
     */
    @Before(Tx.class)
    public Ret addExampleTask(Integer stuId, String tasks, Date startDate, Date date) throws Exception {
        Example example = Example.dao.findFirst("SELECT * FROM `example` WHERE studentId = ?", stuId);
        List<ExampleTaskDTO> taskList = JSONUtil.toList(tasks, ExampleTaskDTO.class);
        //查询任务个数  必须为3
        if (ObjectUtil.isAllEmpty(taskList) || taskList.size() < 3) {
            return Ret.fail().set("error", EnumError.EXAMPLE_TASK_NOT_THREE.getObj());
        }
        if (date == null || startDate == null) {
            return Ret.fail().set("error", EnumError.END_TIME_NOT_ALLOW_NULL.getObj());
        }
        for (ExampleTaskDTO exampleTaskDTO : taskList) {
            if (exampleTaskDTO.getContent().length() > 200) {
                return Ret.fail().set("error", EnumError.EXAMPLE_TASK_TOO_LONG.getObj());
            }
        }
        LocalDateTime localDateTime = DateUtil.toLocalDateTime(date);//LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
        LocalDateTime startLocalDateTime = DateUtil.toLocalDateTime(startDate);
        //如果截止时间小于当前时间
        if (startLocalDateTime.isAfter(localDateTime)) {
            return Ret.fail().set("error", EnumError.DEADLINE_NOT_INCORRECT.getObj());
        }

        HashMap<Integer, StudentExampleTask> hashMap = new HashMap<>();
        //查询已有的任务
        for (ExampleTaskDTO exampleTaskDTO : taskList) {
            Integer taskId = exampleTaskDTO.getTaskId();
            if (taskId != null) {
                //查询当前任务
                StudentExampleTask exTask = StudentExampleTask.dao.findById(taskId);
                if (exTask.getState() == 4) {
                    if (exTask.getDeadline().minusDays(7L).isAfter(LocalDateTime.now())) {
                        localDateTime = exTask.getDeadline();
                    }
                }
                hashMap.put(taskId, exTask);
            }
        }
        //修改任务
        for (ExampleTaskDTO exampleTask : taskList) {
            StudentExampleTask task = new StudentExampleTask();
            Integer taskId = exampleTask.getTaskId();
            String taskname = exampleTask.getContent();
            //验证任务id 如果任务id不为null 则修改任务
            if (taskId != null) {
                //查询当前任务
                StudentExampleTask studentExampleTask = hashMap.get(taskId);
                Integer state = studentExampleTask.getState();
                LocalDateTime deadline = studentExampleTask.getDeadline();
                String content = studentExampleTask.getContent();

                if (state == 4) {
                    //任务审核通过,并且未到截止时间
                    if (!taskname.equals(content)) {
                        if (deadline.compareTo(LocalDateTime.now().plusDays(7L)) > 0) {
                            return Ret.fail().set("error", EnumError.DEADLINE_NOT_COME.getObj());
                        }
                        //设置状态为审核状态
                        studentExampleTask.setState(1);
                        example.setSumState(1);
                    }
                } else {
                    //设置状态为审核状态
                    studentExampleTask.setState(1);
                    example.setSumState(1);
                }
                //设置学生id
                studentExampleTask.setStudentId(stuId);
                //设置任务名称
                studentExampleTask.setContent(taskname);
                //设置任务id
                studentExampleTask.setId(taskId);
                //设置起始日期
                studentExampleTask.setAddTime(startLocalDateTime);
                //设置截止时间
                studentExampleTask.setDeadline(localDateTime);
                studentExampleTask.setUpdateTime(LocalDateTime.now());
                //修改任务
                studentExampleTask.update();
                continue;
            }
            //查询当前学生任务数量
            Integer count = Db.queryInt("select count(studentId) from student_example_task where studentId = ?", stuId);
            //如果任务数量大于等于3  则不能添加新的任务
            if (count >= Const.exampleTaskMaxNum) {
                return Ret.fail().set("error", EnumError.EXAMPLE_TASK_Full.getObj());
            }

            example.setSumState(1);
            //设置状态为审核状态
            task.setState(1);
            //设置学生id
            task.setStudentId(stuId);
            //设置任务名称
            task.setContent(taskname);

            task.setAddTime(startLocalDateTime);
            //设置截止时间
            task.setDeadline(localDateTime);
            //设置周期
            task.setCycle(Const.cycle.EVERYDAY);
            //保存任务
            task.save();
        }
        example.update();
        //发送通知
        TeacherStudent first = TeacherStudent.dao.findFirst("SELECT * FROM teacher_student WHERE studentId = ? AND state = 2", stuId);
        if (BeanUtil.isNotEmpty(first)) {
            List<StudentExampleTask> exTaskList = StudentExampleTask.dao.find("SELECT id FROM student_example_task WHERE studentId = ? AND state = 1", stuId);
            if (ObjectUtil.isAllNotEmpty(exTaskList)) {
                NoticeDTO noticeDTO = new NoticeDTO();
                Cache redis = Redis.use();
                Student o = redis.get(Const.user.Student + stuId);
                noticeDTO.setName(o.getName());
                noticeDTO.setPic(o.getAvatarUrl());
                noticeDTO.setAccountId(o.getAccountId());
                noticeDTO.setSex(o.getSex());
                noticeDTO.setId(stuId);
                noticeDTO.setType(10);
                ArrayList<TaskInfoDTO> taskInfoDTOS = new ArrayList<>();
                TaskInfoDTO taskInfoDTO = new TaskInfoDTO();
                taskInfoDTO.setTaskType(4);
                List<Integer> collect = exTaskList.stream().map(studentExampleTask -> studentExampleTask.getId()).collect(Collectors.toList());
                taskInfoDTO.setTaskIdList(collect);
                taskInfoDTOS.add(taskInfoDTO);
                noticeDTO.setTaskInfos(taskInfoDTOS);
                ArrayList<Integer> list = new ArrayList<>();
                Admin o1 = redis.get(Const.user.Admin + first.getTeacherId());
                list.add(o1.getAccountId());
                try {
                    ChatUtil.sendNotice(JSONUtil.toJsonStr(noticeDTO), 1, list);
                } catch (Exception e) {

                }
            }
        }
        return Ret.ok();
    }

    /**
     * 查询学生添加的榜样任务
     *
     * @param studentId
     * @return
     */
    public Ret getExampleTask(Integer userIdMy, Integer studentId) throws Exception {
    	studentId = studentId == null ? userIdMy : studentId;
        List<StudentExampleTask> setList = StudentExampleTask.dao.find("SELECT * FROM student_example_task WHERE studentId = ? ORDER BY id DESC", studentId);
        return Ret.ok("setList", setList);
    }

    /**
     * 修改榜样
     *
     * @param exId    榜样id
     * @param name    榜样名称
     * @param label   榜样标签
     * @param brief   榜样简介
     * @param keyWord 关键字
     * @param stuId   学生id
     * @return
     */
    @Before(Tx.class)
    public Ret updateExample(String pic, Integer exId, String name, String label, String brief, String keyWord, Integer stuId, String reason, Integer characterType) throws Exception {
        //查询当前榜样
        Example exampleStu = Example.dao.findFirst("select * from example where id = ? and studentId = ? AND isDele = 0", exId, stuId);
        if (BeanUtil.isEmpty(exampleStu)) {
            return Ret.fail().set("error", EnumError.EXAMPLE_NULL.getObj());
        }
        //判断榜样的状态
        if (((exampleStu.getState() == 2 || exampleStu.getState() == 4)) && exampleStu.getCharacterType() != null) {
            return Ret.fail().set("error", EnumError.EXAMPLE_STATE_PASS.getObj());
        }

        if (name == null && brief == null && keyWord == null
                && characterType == null && reason == null
        ) {
            return Ret.fail().set("error", EnumError.EXAMPLE_MUST_UPDATE.getObj());
        }
        //修改榜样
        if (StrUtil.isNotEmpty(name)) {
            exampleStu.setName(name);
        }
        exampleStu.setLabel(label);
        if (StrUtil.isNotEmpty(brief)) {
            exampleStu.setBrief(brief);
        }
        exampleStu.setKeyWord(keyWord);
        exampleStu.setState(1);
        if (characterType != null) {
            exampleStu.setCharacterType(characterType);
        }
        if (StrUtil.isNotEmpty(reason)) {
            exampleStu.setReason(reason);
        }
        if (StrUtil.isNotEmpty(pic)){
            exampleStu.setPictureUrl(pic);
        }
        exampleStu.setUpdateTime(LocalDateTime.now());
        exampleStu.setSumState(1);
        exampleStu.update();

        //查询是否绑定教师 如果绑定教师则发送通知
        TeacherStudent ts = TeacherStudent.dao.findFirst("SELECT * FROM teacher_student WHERE state = 2 AND studentId = ?", stuId);
        if (BeanUtil.isNotEmpty(ts)) {
            //如果已经绑定了教师 则发送通知
            Cache redis = Redis.use();
            Student o = redis.get(Const.user.Student + stuId);
            NoticeDTO noticeDTO = new NoticeDTO();
            noticeDTO.setName(o.getName());
            noticeDTO.setPic(o.getAvatarUrl());
            noticeDTO.setAccountId(o.getAccountId());
            noticeDTO.setSex(o.getSex());
            noticeDTO.setType(10);
            noticeDTO.setId(stuId);
            TaskInfoDTO taskInfoDTO = new TaskInfoDTO();
            taskInfoDTO.setTaskType(3);
            ArrayList<Integer> list = new ArrayList<>();
            list.add(exampleStu.getId());
            taskInfoDTO.setTaskIdList(list);
            ArrayList<TaskInfoDTO> taskInfoDTOS = new ArrayList<>();
            taskInfoDTOS.add(taskInfoDTO);
            noticeDTO.setTaskInfos(taskInfoDTOS);
            ArrayList<Integer> list1 = new ArrayList<>();
            Admin o1 = redis.get(Const.user.Admin + ts.getTeacherId());
            list1.add(o1.getAccountId());
            ChatUtil.sendNotice(JSONUtil.toJsonStr(noticeDTO), 1, list1);
        }
        return Ret.ok();
    }


    /**
     * 展示学生榜样
     *
     * @param curPage
     * @param pageSize
     * @return
     */
    public Ret exhibitExample(Integer studentId, Integer curPage, Integer pageSize) throws Exception {

        Page<Example> paginate = Example.dao.paginate(curPage, pageSize, "select id,name,pictureUrl,label,brief,keyWord", "FROM example where state = 4 AND studentId IS NULL AND isDele = 0");
        Ret ret = Ret.ok("exhibitExamplePage", paginate);
//        if (curPage == 1) {
//            List<Example> list = Example.dao.find("SELECT id,name,pictureUrl,label,brief,keyWord FROM example WHERE studentId = ? AND state = 1", studentId);
//            ret.set("examineExampleList", list);
//        }
        return ret;
    }

/**
 * 删除榜样任务
 *
 * @param stuId  学生id
 * @param taskId
 * @return
 */
//    public Ret delExampleTask(Integer stuId, Integer taskId) throws Exception {
//        //查询指定榜样任务
//        StudentExampleTask exampleTask = StudentExampleTask.dao.findFirst("select * from student_example_task where id= ? and studentId = ?", taskId, stuId);
//        if (BeanUtil.isEmpty(exampleTask)) {
//            return Ret.fail().set("error", EnumError.EXAMPLE_TASK_NULL);
//        }
//        exampleTask.delete();
//        return Ret.ok();
//    }

    /**
     * 查询默认榜样的默认任务
     *
     * @param exId 榜样id
     * @return
     */
    public Ret findDefaultTaskByExampleId(Integer exId) throws Exception {
        List<ExampleTask> taskList = ExampleTask.dao.find("select * from example_task where exampleId = ?", exId);
        return Ret.ok("taskList", taskList);
    }

    /**
     * 查询某榜样的学生成员
     *
     * @param exName
     * @return
     */
    public Ret findStusByExample(Integer stuId, String exName, Integer page, Integer limit) {
        //判断当前学生是否绑定该榜样
        Example example = Example.dao.findFirst("SELECT id FROM `example` WHERE studentId = ? AND name = ? AND isDele =0", stuId, exName);
        if (BeanUtil.isEmpty(example)) {
            return Ret.fail().set("error", EnumError.EXAMPLE_NOT_BIND.getObj());
        }

        Page<Record> records = Db.paginate(page, limit, "SELECT stu.name,stu.id,stu.avatarUrl,stu.clasId ", "FROM example ex INNER JOIN student stu ON stu.id = ex.studentId WHERE ex.name = ? AND ex.isDele = 0", exName);
        return Ret.ok("students", records);
    }

    /**
     * 查询榜样任务过期时间
     *
     * @param stuId
     * @return
     */
    public Ret findExampleDeadLine(Integer stuId) throws Exception {
        //查询榜样的reason,characterType
        Example example = Example.dao.findFirst("SELECT reason,characterType FROM example where studentId = ? AND isDele = 0", stuId);
        Ret ret = Ret.ok().set("exampleNeedRefine", false).set("overdue", 0).set("taskNeedRefine", false);
        if (BeanUtil.isNotEmpty(example)) {
            if (example.getCharacterType() == null || JSONUtil.toList(example.getReason(), String.class).size() != 3) {
                ret.set("exampleNeedRefine", true);
            } else {
                Integer count = Db.queryInt("SELECT COUNT(*) FROM student_example_task stuet WHERE studentId = ?", stuId);
                if (count < 3) {
                    ret.set("taskNeedRefine", true);
                }
            }
        }
        //查询榜样任务时间
        StudentExampleTask studentExampleTask = StudentExampleTask.dao.findFirst("SELECT `addTime`,deadline FROM student_example_task where studentId = ?", stuId);
        if (BeanUtil.isNotEmpty(studentExampleTask)) {
            LocalDateTime deadline = studentExampleTask.getDeadline();
            int i = deadline.compareTo(LocalDateTime.now());
            int j = deadline.compareTo(LocalDateTime.now().plusDays(7L));
            if (i < 0) {
                ret.set("overdue", 1);
            } else if (j < 0) {
                ret.set("overdue", 2);
            }
        }
        return ret;
    }
    
}